﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Xml;

namespace WallpaperControl
{
    public static class Program
    {
        /// <summary>
        /// Der Haupteinstiegspunkt für die Anwendung.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Service.InitStack();
            Application.Run(new MainForm());
        }

        /// <summary>
        /// The icon that appears in system tray when the TrayApp is active.
        /// </summary>
        public static System.Windows.Forms.NotifyIcon mNotifyIcon;
        /// <summary>
        /// The context menu that is shown when the user right-clicks at the TrayIcon.
        /// </summary>
        public static System.Windows.Forms.ContextMenu mTrayMenu;
        /// <summary>
        /// A context menu item of mTrayMenu. Internal use only.
        /// </summary>
        public static System.Windows.Forms.MenuItem mContextMenuItem;
        /// <summary>
        /// The list of images.
        /// </summary>
        public static System.Collections.Generic.List<string> images;
        /// <summary>
        /// The selected ZoomMode for each image item in the list of images.
        /// </summary>
        public static System.Collections.Generic.List<string> ZoomModes;
        /// <summary>
        /// The condition type imported from 'conditiontype.xml'.
        /// </summary>
        public static int ImportedCondType;
        public static int ImportedIntervalIndex;
        /// <summary>
        /// The time condition imported from 'condition.xml'.
        /// </summary>
        public static System.DateTime ImportedTimeCond;
        /// <summary>
        /// The index of the ListBoxItem that is the next wallpaper.
        /// </summary>
        public static int NextItemIndex = 1;
        /// <summary>
        /// Indicates whether the ControlPanel is active.
        /// </summary>
        public static bool ControlPanelActive;

        /// <summary>
        /// Method that loads the 'images.xml' and adds the items to the ListBox
        /// </summary>
        public static void LoadImageListFile()
        {
            try
            {
                System.Xml.XmlDocument XMLdoc = new System.Xml.XmlDocument();
                XMLdoc.Load("images.xml");
                for (int i = 0; i < XMLdoc.DocumentElement.ChildNodes.Count; i++)
                {
                    MainForm.listBoxImages.Items.AddRange(new object[] { XMLdoc.DocumentElement.ChildNodes[i].InnerText });
                    images.AddRange(new string[] { XMLdoc.DocumentElement.ChildNodes[i].InnerText });
                }
            }
            catch (System.Exception)
            {
                MessageBox.Show("Fehler beim Laden der Datei 'images.xml': Es konnten keine Bilder geladen werden.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Method that gets the start mode. This setting is set up in the MainForm.
        /// </summary>
        public static void CheckStartMode()
        {
            Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);

            if (key.GetValue("WallpaperControl") == null)
            {
                MainForm.checkBoxOnSysStart.Checked = false;
            }
            else
            {
                MainForm.checkBoxOnSysStart.Checked = true;
            }
        }

        /// <summary>
        /// Sets the currently selected image as wallpaper.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void UseSelectedWallpaper()
        {
            Wallpaper Wallpaper = new Wallpaper();
            try
            {
                Wallpaper.SetWallpaper(MainForm.listBoxImages.GetItemText(MainForm.listBoxImages.SelectedItem), WallpaperControl.Wallpaper.Style.Stretched);
            }
            catch (System.ArgumentException)
            {
                MessageBox.Show("Der Desktophintergrund konnte nicht gewechselt werden, da sich kein Bild in der Bilderliste befindet.", "Fehler", System.Windows.Forms.MessageBoxButtons.OKCancel, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }
        
        /// <summary>
        /// Sets the next wallpaper on the list. 
        /// </summary>
        public static void UseNextWallpaper()
        {
            Wallpaper Wallpaper = new Wallpaper();
            try
            {
                if (NextItemIndex < MainForm.listBoxImages.Items.Count)
                {
                    Wallpaper.SetWallpaper(MainForm.listBoxImages.GetItemText(MainForm.listBoxImages.Items[NextItemIndex]), Wallpaper.Style.Stretched);
                    NextItemIndex++;
                }
                else
                {
                    if (ImportedCondType == 2 || ConditionForm.ConditionType == 2)
                    {
                        Service.mTimer.Stop();
                    }
                }
            }
            catch (System.ArgumentException)
            {
                MessageBox.Show("Der Desktophintergrund konnte nicht gewechselt werden, da das Hintergrundbild nicht gefunden wurde.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Moves the selected item in the ListBox up.
        /// </summary>
        public static void MoveItemUp()
        {
            int index = MainForm.listBoxImages.SelectedIndex;
            object item = MainForm.listBoxImages.SelectedItem;

            if (index > 0)
            {
                MainForm.listBoxImages.Items.RemoveAt(index);
                MainForm.listBoxImages.Items.Insert(index - 1, item);
                MainForm.listBoxImages.SelectedIndex = index - 1;
            }
        }

        /// <summary>
        /// Moves the selected item in the ListBox down.
        /// </summary>
        public static void MoveItemDown()
        {
            int index = MainForm.listBoxImages.SelectedIndex;
            object item = MainForm.listBoxImages.SelectedItem;

            if (index < MainForm.listBoxImages.Items.Count - 1)
            {
                MainForm.listBoxImages.Items.RemoveAt(index);
                MainForm.listBoxImages.Items.Insert(index + 1, item);
                MainForm.listBoxImages.SelectedIndex = index + 1;
            }
        }

        /// <summary>
        /// Loads the 'condition.xml', in which the current condition is stored (either timer interval or time)
        /// </summary>
        public static void LoadConditionFile()
        {
            System.Xml.XmlDocument ConditionFile = new System.Xml.XmlDocument();
            ConditionFile.Load("condition.xml");
            if (ImportedCondType == 1)
            {
                ImportedTimeCond = System.Convert.ToDateTime(ConditionFile.DocumentElement.InnerText);
            }
            else if (ImportedCondType == 2)
            {
                ImportedIntervalIndex = System.Convert.ToInt32(ConditionFile.DocumentElement.InnerText);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Fehler beim Laden der Datei 'condition.xml': Die gespeicherte Bedingung ist nicht valide.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Loads the 'conditiontype.xml', in which the type of the condition is stored (timer interval = 2, time = 1)
        /// </summary>
        public static void LoadConditionTypeFile()
        {
            //System.IO.FileStream FileStream = new System.IO.FileStream("conditiontype.xml", System.IO.FileMode.OpenOrCreate);
            //System.Xml.Serialization.XmlSerializer XMLSerializer = new System.Xml.Serialization.XmlSerializer(typeof(int));
            //ImportedCondType = XMLSerializer.Deserialize(FileStream,);
            System.Xml.XmlDocument XMLdoc = new System.Xml.XmlDocument();
            try
            {
                XMLdoc.Load("conditiontype.xml");
                ImportedCondType = System.Convert.ToInt32(XMLdoc.DocumentElement.InnerText);
            }
            catch (System.IO.IOException)
            {
                MessageBox.Show("Die Datei 'conditiontype.xml' konnte nicht geöffnet werden.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
            if (ImportedCondType < 1 || ImportedCondType > 2)
                System.Windows.Forms.MessageBox.Show("Fehler beim Laden der Datei 'conditiontype.xml': Der gespeicherte Inhalt ist nicht valide. Die Bedingung konnte nicht erfolgreich geladen werden.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }

    public class Interface
    {
        Service Service = new Service();
        
        /// <summary>
        /// Indicates whether the TrayIcon is currently active.
        /// </summary>
        public bool mTrayIconActive;
        
        public void buttonDelete_Click(object sender, System.EventArgs e)
        {
            Service.RemoveSelectedImage();
        }

        public void buttonCondition_Click(object sender, System.EventArgs e)
        {
            new ConditionForm().Show();
        }

        public void buttonShowNow_Click(object sender, System.EventArgs e)
        {
            Program.UseSelectedWallpaper();
        }

        /// <summary>
        /// Method that saves the setting(s), hides the main form and enters the TrayApp
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void buttonOK_Click(object sender, System.EventArgs e)
        {
            MainForm MainForm = new MainForm();
            if (MainForm.checkBoxOnSysStart.Checked)
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                key.SetValue("WallpaperControl", Application.ExecutablePath.ToString());
            }
            else
            {
                Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run", true);
                key.DeleteValue("WallpaperControl", false);
            }
            Service.CreateImageListFile();
            MainForm.Close();
            DisplayTrayIcon();
            Service.mCheck = true;
            Service.Check();
        }

        public void buttonCancel_Click(object sender, System.EventArgs e)
        {
            HideTrayIcon();
            Service.Exit();
        }

        public void buttonAdd_Click(object sender, System.EventArgs e)
        {
            Service.AddImage();
        }

        public void buttonUp_Click(object sender, System.EventArgs e)
        {
            Program.MoveItemUp();
        }

        public void buttonDown_Click(object sender, System.EventArgs e)
        {
            Program.MoveItemDown();
        }

        public void buttonPreview_Click(object sender, EventArgs e)
        {
            Service.OpenSelectedFile();
        }

        /// <summary>
        /// Enters the TrayApp. This includes the tray icon, the context menu and the balloon tip.
        /// </summary>
        private void DisplayTrayIcon()
        {
            mTrayIconActive = true;

            Program.mNotifyIcon = new System.Windows.Forms.NotifyIcon();
            Program.mNotifyIcon.Icon = new System.Drawing.Icon("icon128.ico");
            Program.mNotifyIcon.Text = "Wallpaper Control";
            Program.mNotifyIcon.Visible = true;
            Program.mNotifyIcon.BalloonTipText = "WallpaperControl wurde in den System Tray minimiert. Klicken Sie mit der rechten Maustaste auf das Symbol, um weitere Optionen anzuzeigen.";
            Program.mNotifyIcon.BalloonTipTitle = "WallpaperControl";
            Program.mNotifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            Program.mNotifyIcon.DoubleClick += new System.EventHandler(mNotifyIcon_DoubleClick);

            Program.mTrayMenu = new System.Windows.Forms.ContextMenu();

            Program.mContextMenuItem = new System.Windows.Forms.MenuItem();
            Program.mContextMenuItem.Text = "ControlPanel anzeigen";
            Program.mContextMenuItem.Click += new System.EventHandler(ContextPanel_Click);
            Program.mTrayMenu.MenuItems.Add(Program.mContextMenuItem);

            Program.mContextMenuItem = new System.Windows.Forms.MenuItem();
            Program.mContextMenuItem.Text = "Nächstes Wallpaper";
            Program.mContextMenuItem.Click += new System.EventHandler(ContextNext_Click);
            Program.mTrayMenu.MenuItems.Add(Program.mContextMenuItem);

            Program.mContextMenuItem = new System.Windows.Forms.MenuItem();
            Program.mContextMenuItem.Text = "Vorheriges Wallpaper";
            Program.mContextMenuItem.Click += new System.EventHandler(ContextPrevious_Click);
            Program.mTrayMenu.MenuItems.Add(Program.mContextMenuItem);

            Program.mContextMenuItem = new System.Windows.Forms.MenuItem();
            Program.mContextMenuItem.Text = "Beenden";
            Program.mContextMenuItem.Click += new System.EventHandler(ContextExit_Click);
            Program.mTrayMenu.MenuItems.Add(Program.mContextMenuItem);

            Program.mNotifyIcon.ContextMenu = Program.mTrayMenu;

            Program.mNotifyIcon.ShowBalloonTip(2000);
        }

        /// <summary>
        /// Shows the MainForm and stops the TrayApp.
        /// </summary>
        private void ShowMainForm()
        {
            mTrayIconActive = false;
            Service.mCheck = false;
            Program.ControlPanelActive = true;
            Program.mNotifyIcon.Visible = false;
            if (Service.mTimer.Enabled)
            {
                Service.mTimer.Stop();
            }
            new MainForm().Show();
        }

        /// <summary>
        /// Hides the TrayIcon.
        /// </summary>
        public void HideTrayIcon()
        {
            if (mTrayIconActive)
            {
                Program.mNotifyIcon.Visible = false;
            }
        }

        void ContextPrevious_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("Das Aufrufen des nächsten Wallpapers wurde noch nicht implementiert.", "Nicht implementiert", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        void ContextNext_Click(object sender, System.EventArgs e)
        {
            MessageBox.Show("Das Aufrufen des nächsten Wallpapers wurde noch nicht implementiert.", "Nicht implementiert", MessageBoxButtons.OK, MessageBoxIcon.Error);
            Program.UseNextWallpaper();
        }

        private void ContextExit_Click(object sender, System.EventArgs e)
        {
            HideTrayIcon();
            Service.Exit();
        }

        private void ContextPanel_Click(object sender, System.EventArgs e)
        {
            ShowMainForm();
        }

        void mNotifyIcon_DoubleClick(object sender, System.EventArgs e)
        {
            ShowMainForm();
        }

        public void listBoxImages_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (MainForm.listBoxImages.SelectedIndex == -1)
            {
                MainForm.buttonDown.Enabled = false;
                MainForm.buttonUp.Enabled = false;
                MainForm.buttonPreview.Enabled = false;
                MainForm.comboBoxStyle.Enabled = false;
            }
            else
            {
                MainForm.buttonDown.Enabled = true;
                MainForm.buttonUp.Enabled = true;
                MainForm.buttonPreview.Enabled = true;
                MainForm.comboBoxStyle.Enabled = true;
            }
        }
    }

    public class Service
    {
        /// <summary>
        /// Contains the number of the image item in ListBox which should be removed.
        /// </summary>
        
        /// <summary>
        /// Indicates whether the App should currently be checking for a wallpaper change.
        /// </summary>
        public static bool mCheck;
        public static int intervalSeconds;

        /// <summary>
        /// The timer object that checks if the wallpaper should be changed.
        /// </summary>
        public static System.Windows.Forms.Timer mTimer;


        /// <summary>
        /// Exits the application.
        /// </summary>
        public void Exit()
        {
            System.Windows.Forms.Application.Exit();
        }

        /// <summary>
        /// Initializes the list which contains the images.
        /// </summary>
        public static void InitStack()
        {
            Program.images = new System.Collections.Generic.List<string>();
        }

        /// <summary>
        /// Checks if the wallpaper should be changed.
        /// </summary>
        public static void Check()
        {
            if (ConditionForm.ConditionType == 1 || Program.ImportedCondType == 1)
            {
                while (mCheck)
                {
                    if (ConditionForm.TimeCondition.Hour == System.DateTime.Now.Hour && ConditionForm.TimeCondition.Minute == System.DateTime.Now.Minute && ConditionForm.TimeCondition.Second == System.DateTime.Now.Second)
                    {
                        Program.UseNextWallpaper();
                    }
                }
            }
            else if (ConditionForm.ConditionType == 2 || Program.ImportedCondType == 2)
            {
                ImportInterval();
                Program.NextItemIndex = 0;
                mTimer = new System.Windows.Forms.Timer();
                if (mCheck)
                {
                    mTimer.Interval = intervalSeconds * 1000;
                    mTimer.Tick += new System.EventHandler(RunTimerEvent);
                    mTimer.Start();
                }
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Es wurde keine Bedingung zum Wechseln des Wallpapers angegeben.", "Fehler", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Imports the interval from the 'condition.xml'.
        /// </summary>
        private static void ImportInterval()
        {
            if (Program.ImportedIntervalIndex == 0)
            {
                intervalSeconds = 30;
            }
            else if (Program.ImportedIntervalIndex == 1)
            {
                intervalSeconds = 60;
            }
            else if (Program.ImportedIntervalIndex == 2)
            {
                intervalSeconds = 180;
            }
            else if (Program.ImportedIntervalIndex == 3)
            {
                intervalSeconds = 300;
            }
            else if (Program.ImportedIntervalIndex == 4)
            {
                intervalSeconds = 600;
            }
            else if (Program.ImportedIntervalIndex == 5)
            {
                intervalSeconds = 900;
            }
            else if (Program.ImportedIntervalIndex == 6)
            {
                intervalSeconds = 1800;
            }
            else if (Program.ImportedIntervalIndex == 7)
            {
                intervalSeconds = 2700;
            }
            else if (Program.ImportedIntervalIndex == 8)
            {
                intervalSeconds = 3600;
            }
            else if (Program.ImportedIntervalIndex == 9)
            {
                intervalSeconds = 7200;
            }
            else if (Program.ImportedIntervalIndex == 10)
            {
                intervalSeconds = 10800;
            }
            else if (Program.ImportedIntervalIndex == 11)
            {
                intervalSeconds = 14400;
            }
            else if (Program.ImportedIntervalIndex == 12)
            {
                intervalSeconds = 18000;
            }
            else if (Program.ImportedIntervalIndex == 13)
            {
                intervalSeconds = 21600;
            }
            else if (Program.ImportedIntervalIndex == 14)
            {
                intervalSeconds = 25200;
            }
            else if (Program.ImportedIntervalIndex == 15)
            {
                intervalSeconds = 28800;
            }
            else if (Program.ImportedIntervalIndex == 16)
            {
                intervalSeconds = 32400;
            }
            else if (Program.ImportedIntervalIndex == 17)
            {
                intervalSeconds = 43200;
            }
            else if (Program.ImportedIntervalIndex == 18)
            {
                intervalSeconds = 64800;
            }
            else if (Program.ImportedIntervalIndex == 19)
            {
                intervalSeconds = 86400;
            }
            else if (Program.ImportedIntervalIndex == 20)
            {
                intervalSeconds = 172800;
            }
            else if (Program.ImportedIntervalIndex == 21)
            {
                intervalSeconds = 5;
            }
            else
            {
                MessageBox.Show("Das Intervall, in dem das Wallpaper gewechselt werden soll, konnte nicht ermittelt werden.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Saves the images to the 'images.xml'.
        /// </summary>
        public void CreateImageListFile()
        {
            try
            {
                System.IO.FileStream SaveFileStream = new System.IO.FileStream("images.xml", System.IO.FileMode.Create);
                System.Xml.Serialization.XmlSerializer Serializer = new System.Xml.Serialization.XmlSerializer(typeof(System.Collections.Generic.List<string>));
                Serializer.Serialize(SaveFileStream, Program.images);
                SaveFileStream.Close();
            }
            catch (System.Exception)
            {
                if (MessageBox.Show("Fehler beim Erstellen der Datei 'images.xml'.", "Fehler", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error) == DialogResult.Retry)
                {
                    CreateImageListFile();
                }
            }
        }

        /// <summary>
        /// Opens the selected image in the ListBox with the standard associated program.
        /// </summary>
        public void OpenSelectedFile()
        {
            try
            {
                System.Diagnostics.Process.Start(MainForm.listBoxImages.GetItemText(MainForm.listBoxImages.SelectedItem));
            }
            catch (System.Exception)
            {
                System.Windows.Forms.MessageBox.Show("Die angegebene Datei konnte nicht gefunden werden.", "Fehler", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Contains the event that is called when the timer is finished.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void RunTimerEvent(object sender, EventArgs e)
        {
            Program.UseNextWallpaper();
        }

        /// <summary>
        /// Removes the currently selected image from the list.
        /// </summary>
        public void RemoveSelectedImage()
        {
            try
            {
                int deleteIndex;
                deleteIndex = MainForm.listBoxImages.SelectedIndex;
                Program.images.RemoveAt(deleteIndex);
                MainForm.listBoxImages.Items.Remove(MainForm.listBoxImages.SelectedItem);
            }
            catch (System.ArgumentException)
            {
                MessageBox.Show("Fehler beim Entfernen des Bildes aus WallpaperControl.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Adds a new image to the list.
        /// </summary>
        public void AddImage()
        {
            string FilePath;
            System.Windows.Forms.OpenFileDialog AddImageDialog = new System.Windows.Forms.OpenFileDialog();
            AddImageDialog.Filter = "Bitmaps|*.bmp";
            AddImageDialog.Title = "Bild hinzufügen...";

            if (AddImageDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                FilePath = System.IO.Path.GetFullPath(AddImageDialog.FileName);
                Program.images.Add(FilePath);
                MainForm.listBoxImages.Items.Insert(0, FilePath);
            }
        }
    }
}
